<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    /*
        1.实例化
             再次说明new关键字的作用, 使用 new 调用类的构造函数会执行如下操作。
                (1) 在内存中创建一个新对象。
                (2) 这个新对象内部的[[Prototype]]指针被赋值为构造函数的 prototype 属性。 (3) 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)。
                (4) 执行构造函数内部的代码(给新对象添加属性)。
                (5) 如果构造函数返回非空对象，则返回该对象;否则，返回刚创建的新对象。
     */
    class Animal {
    }

    class Person1 {
        constructor() {
            console.log('person constructor')
        }
    }

    class Vegetable {
        constructor() {
            this.color = 'orange'
        }
    }

    let a = new Animal();
    let p = new Person1();   // person constructor
    let v = new Vegetable();
    console.log(v.color)    // orange


    /*
        1.2.constructor的返回
            默认情况下，类构造函数会在执行之后返回 this 对象
     */

    class Person {
        constructor(override) {
            this.foo = 'foo'
            if (override) {
                return {bar: 'bar'}
            }
        }
    }

    let p1 = new Person(),
        p2 = new Person(true)
    console.log(p1)
    console.log(p1 instanceof Person);  // true
    console.log(p2)
    console.log(p2 instanceof Person) // false

    /*
        1.3 类构造函数必须使用new操作符
     */

    /*
        2. 把类当成特殊函数
     */
    console.log('---2---')

    class Person2 {
    }

    console.log(Person2)
    console.log(typeof Person2) // function

    console.log(Person2 === Person2.prototype.constructor) // true
    let p2_1 = new Person2();
    console.log(p2_1 instanceof Person2)

    /*
        3.类也可以像其他对象或函数引用一样把类作为参数传递
     */
    let classList = [
        class {
            constructor(id) {
                this.id_ = id;
                console.log(`instance ${this.id_}`)
            }
        }
    ]

    function createInstance(classDefinition, id) {
        return new classDefinition(id)
    }

    let foo = createInstance(classList[0], 1314)

    /*
        4.类也可以立即实例化
     */
    let p4 = new class Foo {
        constructor(x) {
            console.log(x)
        }
    }('bar')
    console.log(p4)
</script>
</body>
</html>